/**
 * Title:       XMLEnvelope.java
 * Copyright:   Copyright (c) 1996-2004 The Agent Factory Working Group. All rights reserved.
 * Licence:     This file is free software; you can redistribute it and/or modify
 *              it under the terms of the GNU Lesser General Public License as published by
 *              the Free Software Foundation; either version 2.1, or (at your option)
 *              any later version.
 *
 *              This file is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *              GNU Lesser General Public License for more details.
 *
 *              You should have received a copy of the GNU Lesser General Public License
 *              along with Agent Factory; see the file COPYING.  If not, write to
 *              the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *              Boston, MA 02111-1307, USA.
 */
package com.agentfactory.platform.mts;

import com.agentfactory.platform.core.AgentID;
import java.util.ArrayList;

/**
 * This is a concrete implementation of the Envelope class that parses
 * some text that contains an XML version of the envelope.
 *
 * @author  Rem Collier
 */
public class XMLEnvelope extends Envelope {
    public XMLEnvelope() {
        to = new ArrayList();
        intendedReceiver = new ArrayList();
    }

    /**
     * This factory method returns an ArrayList of XMLEnvelope objects - one
     * per envelope defined in the message.
     *
     * @param text the XML in string format
     * @return an ArrayList of XMLEnvelope objects!
     */
    public static ArrayList newInstance(String text) {
        ArrayList envelopes = new ArrayList();
        ArrayList list = (ArrayList) Node.parseXML(text);
        Node node = null;
        for (int j = 0; j < list.size(); j++) {
            node = (Node) list.get(j);
            if (node.getName().equals("envelope")) {
                for (int i = 0; i < node.numChildren(); i++) {
                    envelopes.add(newEnvelope((Node) node.getChild(i)));
                }
            }
        }
        
        return envelopes;
    }

    /**
     * This method creates a new envelope based upon the XML passed in to
     * it.
     *
     * @param node a param XML node.
     * @return an XMLEnvelope object4
     */
    private static XMLEnvelope newEnvelope(Node node) {
        XMLEnvelope envelope = new XMLEnvelope();
        for (int i = 0; i < node.numChildren(); i++) {
            parseNode(envelope, (Node) node.getChild(i));
        }
        
        return envelope;
    }
    
    /**
     * Method is called by the newEnvelope method to process contents of
     * the XML envelope.
     *
     * @param envelope the XMLEnvelope object under construction.
     * @param node the XML node to be parsed.
     */
    private static void parseNode(XMLEnvelope envelope, Node node) {
        if (node.getName().equals("to")) {
            // We have the to field of the envelope, so locate and parse
            // each agent-identifier node (there may be many).
            for (int i = 0; i < node.numChildren(); i++) {
                envelope.getTo().add(new AgentID((Node) node.getChild(i)));
            }
        } else if (node.getName().equals("intended-receiver")) {
            // We have the to field of the envelope, so locate and parse
            // each agent-identifier node (there may be many).
            for (int i = 0; i < node.numChildren(); i++) {
                envelope.getIntendedReceiver().add(new AgentID((Node) node.getChild(i)));
            }
        } else if (node.getName().equals("from")) {
            // We have the from field of the envelope, so locate and parse
            // the agent-identifier node (there should be only one).
            for (int i = 0; i < node.numChildren(); i++) {
                envelope.setFrom(new AgentID((Node) node.getChild(i)));
            }
        } else if (node.getName().equals("acl-representation")) {
            // We have the acl-representation field of the envelope, so
            // retrieve the contents (it should be trimmed to remove any
            // superflouous spaces).
            envelope.setAclRepresentation(((String) node.getChild(0)).trim());
        }
    }
    
    /**
     * Create a String that containing the message envelope in a form that
     * is compliant with the FIPA XML Specification.
     *
     * @return an xml String
     */
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("<?xml version=\"1.0\"?>\n");
        buf.append("<envelope>\n");
        buf.append("\t<params index=\"1\">\n");
        buf.append("\t\t<to>\n");
        
        AgentID aid = null;
        for (int i = 0; i < to.size(); i++) {
            aid = (AgentID) to.get(i);
            aid.toXMLString(buf, "\t\t\t");
        }
        buf.append("\t\t</to>\n");
        buf.append("\t\t<from>\n");
        from.toXMLString(buf, "\t\t\t");
        buf.append("\t\t</from>\n");
        buf.append("\t\t<acl-representation>" + aclRepresentation + "</acl-representation>\n");
        buf.append("\t\t<payload-length>" + payloadLength + "</payload-length>\n");
        buf.append("\t\t<intended-receiver>\n");
        
        for (int i = 0; i < intendedReceiver.size(); i++) {
            aid = (AgentID) intendedReceiver.get(i);
            aid.toXMLString(buf, "\t\t\t");
        }
        buf.append("\t\t</intended-receiver>\n");
        buf.append("\t</params>\n");
        buf.append("</envelope>");
        return buf.toString();
    }
}
